package com.hxl.tech.gateway.auth.util;


import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.hxl.tech.gateway.auth.dto.openapi.OpenApiApprovalDTO;
import com.hxl.tech.gateway.auth.dto.openapi.OpenApiFindDTO;
import com.hxl.tech.gateway.auth.dto.resource.ResourceFindDTO;
import com.hxl.tech.gateway.auth.model.*;
import com.hxl.tech.gateway.auth.service.*;
import com.hxl.tech.gateway.common.constant.AppConstant;
import com.hxl.tech.gateway.common.dto.LimitRuleDTO;
import com.hxl.tech.gateway.common.util.RedisUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class AppInitUtil {

    private final ApplicationService applicationService;
    private final OpenApiService openApiService;
    private final ResourceService resourceService;
    private final LimitRuleService limitRuleService;
    private final OpenApiApprovalService openApiApprovalService;

    public void freshOpenUrl() {

        ResourceFindDTO findDTO = new ResourceFindDTO();
        findDTO.setResourceType(AppConstant.RESOURCE_OPEN_URL);
        List<Resource> resources = resourceService.find(findDTO);
        for (Resource r : resources) {
            String key = AppConstant.REDIS_OPEN_URL_PREFIX + r.getId().getMerchantCode();
            RedisUtil.set(key, r.getResourceValue(), 0, TimeUnit.DAYS);
        }
    }

    public void freshApplication() {

        List<Application> applications = applicationService.findAll();
        for (Application application : applications) {
            String key = AppConstant.REDIS_APP_PREFIX + application.getAppId();
            RedisUtil.set(key, JSONObject.toJSONString(application), 0, TimeUnit.DAYS);
        }
    }

    public void freshApi() {

        List<OpenApi> openApis = openApiService.find(new OpenApiFindDTO());
        for (OpenApi openApi : openApis) {
            String key = AppConstant.REDIS_API_PREFIX + openApi.getApiName();
            RedisUtil.set(key, JSONObject.toJSONString(openApi), 0, TimeUnit.DAYS);
        }
    }

    public void freshLimitIp() {

        Resource resource = resourceService.read(new Resource.Id(AppConstant.RESOURCE_MERCHANT_DEFAULT, AppConstant.RESOURCE_IP_LIMIT));
        if (Objects.nonNull(resource)) {
            RedisUtil.set(AppConstant.REDIS_LIMIT_IP_RULE, resource.getResourceValue(), 0, TimeUnit.DAYS);
        }
    }

    public void freshLimitRate() {

        List<LimitRule> limitRules = limitRuleService.findAll();
        for (LimitRule limitRule : limitRules) {
            String key = limitRule.getRuleId() + "_" + limitRule.getAppId() + "_" +limitRule.getMerchantCode() + "_"  + limitRule.getApiName();
            RedisUtil.set(AppConstant.REDIS_LIMIT_RATE_RULE + key, JSONObject.toJSONString(limitRule), 0, TimeUnit.DAYS);
        }
    }

    public void freshApiApproval() {

        List<OpenApiApproval> openApiApprovals = openApiApprovalService.find(null);
        if (CollUtil.isEmpty(openApiApprovals)) {
            return;
        }

        List<OpenApiApprovalDTO> openApiApprovalDTOS = CopyUtil.toList(openApiApprovals, OpenApiApprovalDTO.class);
        Map<String, List<OpenApiApprovalDTO>> map = openApiApprovalDTOS.stream().collect(Collectors.groupingBy(OpenApiApprovalDTO::getAppId));
        for (String appId : map.keySet()) {
            String appKey = AppConstant.REDIS_API_APPROVAL_PREFIX + appId;
            List<String> apis = map.get(appKey).stream().map(OpenApiApprovalDTO::getApiName).distinct().collect(Collectors.toList());
            RedisUtil.set(appKey, String.join(",", apis), 0, TimeUnit.MINUTES);
        }
    }
}
